package cn.tedu.mall.order.listener;

import cn.tedu.mall.common.exception.CoolSharkServiceException;
import cn.tedu.mall.order.mappers.OrderItemMapper;
import cn.tedu.mall.order.mappers.OrderMapper;
import cn.tedu.mall.pojo.order.dto.OrderAddCondition;
import cn.tedu.mall.pojo.order.model.OmsOrder;
import cn.tedu.mall.pojo.order.model.OmsOrderItem;
import cn.tedu.mall.pojo.seckill.dto.SeckillOrderAddDTO;
import cn.tedu.mall.pojo.seckill.dto.SeckillOrderItemAddDTO;
import cn.tedu.mall.seckill.service.ISeckillSkuService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Component
@Slf4j
public class OrderAddListenerSeckillAddImpl implements OrderAddListenerExecutorInter, InitializingBean {

    @DubboReference
    private ISeckillSkuService seckillSkuService;

    @Autowired// 操作表格 oms_order
    private OrderMapper orderMapper;

    @Autowired// 操作表格 oms_order_item
    private OrderItemMapper orderItemMapper;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    @Override
    public void afterPropertiesSet() throws Exception {
        OrderAddListenerRegister.register(SeckillOrderAddDTO.class.getName(), this);
    }

    /**
     * 负责处理秒杀下单的新增事务逻辑
     * @param orderAddCondition
     * @return
     */
    @Override
    public RocketMQLocalTransactionState execute(OrderAddCondition orderAddCondition) {
        SeckillOrderAddDTO seckillOrderAddDTO = (SeckillOrderAddDTO) orderAddCondition;
        // 减库存 远程调用 skuId quantity
        SeckillOrderItemAddDTO seckillOrderItemAddDTO = seckillOrderAddDTO.getSeckillOrderItemAddDTO();
        try {
            seckillSkuService.redusSeckillSkuCount(seckillOrderItemAddDTO, seckillOrderAddDTO.getSn());
        } catch (CoolSharkServiceException e) {
            // 减库存失败
            log.error("业务异常：{}", e.getMessage());
            return RocketMQLocalTransactionState.ROLLBACK;
        }
        // 新增订单 oms_order表
        OmsOrder omsOrder = new OmsOrder();
        // 封装数据
        BeanUtils.copyProperties(seckillOrderAddDTO, omsOrder);
        // 业务方还需要将omsOrder种缺少的字段补齐
        replenishOrder(omsOrder);
        // 先新增订单得到订单id
        try {
            // 新增完成后会将id回填到omsOrder对象中
            orderMapper.insertOrder(omsOrder);
        } catch (Exception e) {
            log.error("业务异常：{}", e.getMessage());
            return RocketMQLocalTransactionState.UNKNOWN;
        }
        // 新增订单商品（秒杀下单中只有单个seckillOrderItemAddDTO，不用循环转化为持久层对象）
        List<OmsOrderItem> omsOrderItems = new ArrayList<>();
//        List<OrderItemAddDTO> orderItems = orderAddDTO.getOrderItems();
//        for (OrderItemAddDTO orderItem : orderItems) {
//            OmsOrderItem omsOrderItem = new OmsOrderItem();
//            // 转化
//            BeanUtils.copyProperties(orderItem, omsOrderItem);
//            // omsOrderItemList中添加元素，omsOrderItem中想办法添加orderId
//            omsOrderItem.setOrderId(omsOrder.getId());
//            omsOrderItems.add(omsOrderItem);
//        }
        OmsOrderItem omsOrderItem = new OmsOrderItem();
        // 转化
        BeanUtils.copyProperties(seckillOrderItemAddDTO, omsOrderItem);
        omsOrderItems.add(omsOrderItem);

        try {
            orderItemMapper.insertOrderItems(omsOrderItems);
        } catch (Exception e) {
            log.error("业务异常：{}", e.getMessage());
            e.printStackTrace();
            return RocketMQLocalTransactionState.UNKNOWN;
        }
        // 订单新增的时候，有超时未支付的检查
        // 发送一个延迟队列，在消息中添加一个延迟级别的头 默认0 不延迟
        Message msg = MessageBuilder
                .withPayload(seckillOrderAddDTO.getSn() + "," + seckillOrderAddDTO.getSeckillOrderItemAddDTO().getSkuId())
                .build();
        //【1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h】(延迟级别)
        SendResult result = rocketMQTemplate.syncSend("csmall-order-delay-topic:seckillDelay", msg, 1000 * 5, 16);// timeout(连接超时时间) delayLevel(延迟时间)
        if (result.getSendStatus().toString().equals("SEND_OK")) {
            return RocketMQLocalTransactionState.COMMIT;
        } else {
            log.error("延迟消息发送失败，记录日志，手动，人工处理");
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }

    private void replenishOrder(OmsOrder omsOrder) {
        // 订单状态 默认 未支付0 已关闭1
        omsOrder.setState(0);
        // 时间字段 创建时间 修改时间 订单新增时间
        LocalDateTime now = LocalDateTime.now();
        omsOrder.setGmtOrder(now);
        omsOrder.setGmtCreate(now);
        omsOrder.setGmtModified(now);
        // UNDO 添加价格，并且追加校验规则
    }
}
